#include <REGX52.H>
#include "Timer0.h"
#include "Int0.h"



/*****************变量定义*******************/

//状态为 0  --  空闲
//状态为 1  --  寻找开始或者重发时序
//状态为 2  --  开始解码32位数据
unsigned char IR_State;		//设置状态

unsigned int IR_Time;		//记录时间

unsigned char IR_Data[4];	//储存数据
unsigned char IR_pData;		//定位数据

unsigned char IR_DataFlag;		//标记数据
unsigned char IR_RepeatFlag;	//标记重发

unsigned char IR_Address;	//接受地址
unsigned char IR_Command;	//接受命令

/********************************************/



/**
  * @brief   红外初始化
  * @param   无
  * @retval  无
  */
void IR_Init()
{
	Timer0_Init();	//定时器0初始化
	Int0_Init();	//外部中断0初始化
}



/**
  * @brief  红外遥控获取收到数据帧标志位
  * @param  无
  * @retval 是否收到数据帧，1为收到，0为未收到
  */
unsigned char IR_GetDataFlag()
{
	if (IR_DataFlag)
	{
		IR_DataFlag = 0;
		return 1;
	}
	return 0;
}


/**
  * @brief  红外遥控获取收到连发帧标志位
  * @param  无
  * @retval 是否收到连发帧，1为收到，0为未收到
  */
unsigned char IR_GetRepeatFlag()
{
	if(IR_RepeatFlag)
	{
		IR_RepeatFlag = 0;
		return 1;
	}
	return 0;
}


/**
  * @brief  红外遥控获取收到的地址数据
  * @param  无
  * @retval 收到的地址数据
  */
unsigned char IR_GetAddress()
{
	return IR_Address;
}
	

/**
  * @brief  红外遥控获取收到的命令数据
  * @param  无
  * @retval 收到的命令数据
  */
unsigned char IR_GetCommand()
{
	return IR_Command;
}



//外部中断0中断函数，下降沿触发执行
void Int0_Routine(void) interrupt 0
{
	if (IR_State == 0)			//状态0，空闲状态
	{
		Timer0_SetCounter(0);	//定时计数器清0
		Timer0_Run(1);			//定时器启动
		IR_State = 1;			//置状态为1
	}
	else if (IR_State == 1)		//状态1，等待Start信号或Repeat信号
	{
		IR_Time = Timer0_GetCounter();	//获取上一次中断到此次中断的时间
		Timer0_SetCounter(0);	//定时计数器清0
		//如果计时为13.5ms，则接收到了Start信号（判定值在12MHz晶振下为13500，在11.0592MHz晶振下为12442）
		if (IR_Time > 12442 - 500 && IR_Time < 12442 + 500)
		{
			IR_State = 2;			//置状态为2
		}
		//如果计时为11.25ms，则接收到了Repeat信号（判定值在12MHz晶振下为11250，在11.0592MHz晶振下为10368）
		else if (IR_Time > 10368 - 500 && IR_Time < 10368 + 500)
		{
			IR_RepeatFlag = 1;	//置收到连发帧标志位为1
			Timer0_Run(0);		//定时器停止
			IR_State = 0;		//置状态为0
		}
		else					//接收出错
		{
			IR_State = 1;		//置状态为1
		}
	}
	else if(IR_State == 2)		//状态2，接收数据
	{
		IR_Time = Timer0_GetCounter();	//获取上一次中断到此次中断的时间
		Timer0_SetCounter(0);	//定时计数器清0
		//如果计时为1120us，则接收到了数据0（判定值在12MHz晶振下为1120，在11.0592MHz晶振下为1032）
		if(IR_Time > 1032-500 && IR_Time < 1032+500)
		{
			IR_Data[IR_pData/8] &= ~(0x01 << (IR_pData%8));	//数据对应位置1
			IR_pData++;		//数据位置指针自增
		}
		//如果计时为2250us，则接收到了数据1（判定值在12MHz晶振下为2250，在11.0592MHz晶振下为2074）
		else if(IR_Time > 2074-500 && IR_Time < 2074+500)
		{
			IR_Data[IR_pData/8] |= (0x01 << (IR_pData%8));
			IR_pData++;
		}
		//接收出错
		else					
		{
			IR_pData=0;			//数据位置指针清0
			IR_State=1;			//置状态为1
		}
		if (IR_pData >= 32)		//如果接收到了32位数据
		{
			IR_pData = 0;			//数据位置指针清0
			if ((IR_Data[0] == ~IR_Data[1]) && (IR_Data[2] == ~IR_Data[3]))	//数据验证
			{
				IR_Address = IR_Data[0];	//转存数据
				IR_Command = IR_Data[2];
				IR_DataFlag = 1;	//置收到连发帧标志位为1

			}
			Timer0_Run(0);		//定时器停止
			IR_State = 0;		//置状态为0
		}
	}	
}














